﻿using System;
using ESRI.ArcGIS.NetworkAnalyst;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ESRI.ArcGIS;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataManagementTools;
using System.IO;
using ESRI.ArcGIS.Output;
using System.Diagnostics;
using ESRI.ArcGIS.SystemUI;
using stdole;
using System.Threading;


namespace Arcgis
{
    public partial class Form1 : Form
    {
        private IPoint m_startPoint = null; // 起点
        private IPoint m_endPoint = null;   // 终点
        private IGraphicsContainer m_graphicsContainer = null; // 用于绘制路径的图形容器
        private IElement m_routeElement = null; // 存储路径元素
        // 获取地图控件引用
        public AxMapControl GetMapControl()
        {
            return axMapControl1;
        }

        // 安全执行地图操作（线程安全）
        public void SafeMapAction(Action<AxMapControl> action)
        {
            if (axMapControl1.InvokeRequired)
            {
                axMapControl1.BeginInvoke(new MethodInvoker(() => action(axMapControl1)));
            }
            else
            {
                action(axMapControl1);
            }
        }
        public Form1()
        {
            InitializeComponent();

            if (!RuntimeManager.Bind(ProductCode.EngineOrDesktop))
            {
                MessageBox.Show("ArcGIS运行时绑定失败，请检查安装！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }

            try
            {
                InitializeHawkEye();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"初始化失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            string mxdPath = @"D:\MyGIS\sj\长沙市.mxd"; // 替换为你自己的路径
            if (System.IO.File.Exists(mxdPath))
            {
                try
                {
                    axMapControl1.LoadMxFile(mxdPath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"加载 MXD 失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show($"找不到指定的 MXD 文件: {mxdPath}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitializeHawkEye();
        }

        private void InitializeHawkEye()
        {
            try
            {
                if (axMapControl1 == null || axMapControl2 == null)
                    throw new Exception("地图控件未初始化");

                axMapControl2.Map.ClearLayers();
                axMapControl1.OnExtentUpdated += axMapControl1_OnExtentUpdated;
                axMapControl1.OnMapReplaced += axMapControl1_OnMapReplaced;
                axMapControl2.OnMouseMove += axMapControl2_OnMouseMove;

                UpdateHawkEyeView();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"鹰眼初始化失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void UpdateHawkEyeView()
        {
            try
            {
                axMapControl2.Map.ClearLayers();
                ILayer overviewLayer = GetOverviewLayer(axMapControl1.Map);
                if (overviewLayer != null)
                {
                    axMapControl2.AddLayer(overviewLayer);
                    axMapControl2.Extent = axMapControl1.FullExtent;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("更新鹰眼视图时出错: " + ex.Message);
            }
        }

        private ILayer GetOverviewLayer(IMap map)
        {
            try
            {
                int layerCount = map.LayerCount;

                ILayer overviewLayer = map.get_Layer(0);
                for (int i = 1; i < layerCount; i++)
                {
                    ILayer candidateLayer = map.get_Layer(i);
                    if (candidateLayer.AreaOfInterest != null &&
                        candidateLayer.AreaOfInterest.Width > overviewLayer.AreaOfInterest.Width)
                    {
                        overviewLayer = candidateLayer;
                    }
                }
                return overviewLayer;
            }
            catch (Exception ex)
            {
                // 添加日志记录或返回null
                Console.WriteLine($"获取概览图层时出错: {ex.Message}");
                return null;
            }
        }

        private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e)
        {
            IEnvelope pEnv = (IEnvelope)e.newEnvelope;
            IRectangleElement pRectangleEle = new RectangleElement() as IRectangleElement;
            IElement pEle = pRectangleEle as IElement;
            pEle.Geometry = pEnv;

            IRgbColor pColor = new RgbColor() as IRgbColor;
            pColor.Red = 255; pColor.Green = 0; pColor.Blue = 0; pColor.Transparency = 255;

            ILineSymbol pOutline = new SimpleLineSymbol() as ILineSymbol;
            pOutline.Width = 2; pOutline.Color = pColor;

            pColor.Transparency = 0;
            IFillSymbol pFillSymbol = new SimpleFillSymbol() as IFillSymbol;
            pFillSymbol.Color = pColor; pFillSymbol.Outline = pOutline;

            IFillShapeElement pFillShapeEle = pEle as IFillShapeElement;
            pFillShapeEle.Symbol = pFillSymbol;

            IGraphicsContainer pGra = axMapControl2.Map as IGraphicsContainer;
            IActiveView pAv = pGra as IActiveView;
            pGra.DeleteAllElements();
            pGra.AddElement((IElement)pFillShapeEle, 0);
            pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }

        private void axMapControl2_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            try
            {
                if (e.button != 1) return;

                IPoint pPoint = new ESRI.ArcGIS.Geometry.Point() as IPoint;
                pPoint.PutCoords(e.mapX, e.mapY);
                axMapControl1.CenterAt(pPoint);
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
            }
            catch (Exception ex)
            {
                MessageBox.Show("鹰眼地图鼠标移动处理出错: " + ex.Message);
            }
        }

        private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
        {
            UpdateHawkEyeView();
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            try
            {
                axMapControl1.Dispose();
                axMapControl2.Dispose();
            }
            catch { }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            var searchForm = new SearchForm(this);
            searchForm.Show();
        }

        private async void btnRoutePlanning_Click(object sender, EventArgs e)
        {
            try
            {
                string gdbPath = @"D:\MyGIS\sj\新建文件夹\新建文件地理数据库.gdb";
                string datasetName = "road";
                string sourceShpPath = @"D:\MyGIS\sj\新建文件夹\road.shp";
                IWorkspace gdbWorkspace;

                // 检测.gdb实际路径
                string actualGdbPath = System.IO.Path.ChangeExtension(gdbPath, ".gdb");
                if (Directory.Exists(actualGdbPath))
                {
                    MessageBox.Show("地理数据库已存在，直接使用现有数据库", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    IWorkspaceFactory factory = new FileGDBWorkspaceFactoryClass();
                    gdbWorkspace = factory.OpenFromFile(gdbPath, 0);
                }
                // 验证起点终点已选择
                if (m_startPoint == null || m_endPoint == null)
                {
                    MessageBox.Show("请先选择起点和终点", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                FindShortestPath(m_startPoint, m_endPoint);
                await Task.Delay(4000);
                MoveResultLayerToTop();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void MoveResultLayerToTop()
        {
            try
            {
                IMap map = axMapControl1.Map; 
                ILayer resultLayer = null;
                for (int i = 0; i < map.LayerCount; i++)
                {
                    if (map.get_Layer(i).Name == "result")
                    {
                        resultLayer = map.get_Layer(i);
                        break;
                    }
                }
                if (resultLayer != null)
                {
                    map.DeleteLayer(resultLayer);
                    map.AddLayer(resultLayer);
                    if (resultLayer is IFeatureLayer featureLayer)
                    {
                        // 创建高亮显示符号（红色，宽度2）
                        ISimpleLineSymbol highlightSymbol = new SimpleLineSymbolClass()
                        {
                            Color = new RgbColorClass() { Red = 255, Green = 0, Blue = 0 },
                            Width = 2,
                            Style = esriSimpleLineStyle.esriSLSSolid
                        };

                        // 应用高亮符号
                        IGeoFeatureLayer geoFeatureLayer = (IGeoFeatureLayer)featureLayer;
                        ISimpleRenderer simpleRenderer = new SimpleRendererClass();
                        simpleRenderer.Symbol = (ISymbol)highlightSymbol;
                        geoFeatureLayer.Renderer = (IFeatureRenderer)simpleRenderer;
                    }
                    axMapControl1.Refresh();
                }
            }
            catch (Exception ex)
            {
                
            }
        }

        private IWorkspace CreateFileGeodatabase(string targetGdbPath)
        {
            IWorkspace workspace = null;
            IWorkspaceName tempWorkspaceName = null;
            try
            {
                // 分解目标路径
                string targetDirectory = System.IO.Path.GetDirectoryName(targetGdbPath);
                string targetGdbName = System.IO.Path.GetFileNameWithoutExtension(targetGdbPath);
                string finalGdbPath = System.IO.Path.Combine(targetDirectory, targetGdbName + ".gdb");

                // 创建父目录（如果不存在）
                if (!Directory.Exists(targetDirectory))
                {
                    Directory.CreateDirectory(targetDirectory);
                }

                // 如果目标已存在则直接打开
                if (Directory.Exists(finalGdbPath))
                {
                    return new FileGDBWorkspaceFactoryClass().OpenFromFile(targetDirectory, 0);
                }

                // 生成临时名称（使用GUID避免冲突）
                string tempGdbName = "temp_" + Guid.NewGuid().ToString("N");
                string tempGdbPath = System.IO.Path.Combine(targetDirectory, tempGdbName + ".gdb");

                // 创建临时地理数据库
                IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactoryClass();
                tempWorkspaceName = workspaceFactory.Create(targetDirectory, tempGdbName, null, 0);

                // 关键修复点1：强制释放所有COM引用
                Marshal.FinalReleaseComObject(tempWorkspaceName);
                tempWorkspaceName = null;
                workspaceFactory = null;

                // 关键修复点2：等待系统释放文件锁
                System.Threading.Thread.Sleep(500); // 等待500ms
                GC.Collect();
                GC.WaitForPendingFinalizers();

                // 重命名物理目录
                Directory.Move(tempGdbPath, finalGdbPath);

                // 关键修复点3：重新初始化工作空间工厂
                workspaceFactory = new FileGDBWorkspaceFactoryClass();

                // 关键修复点4：使用完整路径打开
                workspace = workspaceFactory.OpenFromFile(finalGdbPath, 0);
                return workspace;
            }
            catch (COMException comEx)
            {
                // 清理残留临时文件
                if (tempWorkspaceName != null)
                {
                    string tempPath = ((IWorkspaceName)tempWorkspaceName).PathName;
                    if (Directory.Exists(tempPath))
                    {
                        Directory.Delete(tempPath, true);
                    }
                }
                throw new Exception($"操作失败(0x{comEx.ErrorCode:X8}): {comEx.Message}");
            }
            finally
            {
                // 显式释放COM对象
                if (tempWorkspaceName != null) Marshal.ReleaseComObject(tempWorkspaceName);
            }
        }

        private IFeatureDataset CreateFeatureDataset(IWorkspace workspace, string datasetName, ISpatialReference spatialRef)
        {
            try
            {
                IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
                IFeatureDataset featureDataset = featureWorkspace.CreateFeatureDataset(datasetName, spatialRef);
                return featureDataset;
            }
            catch (Exception ex)
            {
                throw new Exception($"要素数据集创建失败: {ex.Message}");
            }
        }

        private ISpatialReference CreateUTM49NSpatialReference()
        {
            try
            {
                // 1. 创建坐标系工厂
                ISpatialReferenceFactory3 spatialRefFactory = new SpatialReferenceEnvironmentClass();

                // 2. 创建 UTM Zone 49N 投影坐标系
                IProjectedCoordinateSystem utm49N = spatialRefFactory.CreateProjectedCoordinateSystem(32649); // WKID 32649

                // 3. 禁用 Z 坐标系（通过设置垂直坐标系为 null）
                // 使用 ISpatialReference3 接口操作
                ISpatialReference3 spatialRef3 = (ISpatialReference3)utm49N;
                spatialRef3.VerticalCoordinateSystem = null;

                // 4. 设置默认 XY 容差
                ISpatialReferenceTolerance spatialTolerance = (ISpatialReferenceTolerance)utm49N;
                spatialTolerance.SetDefaultXYTolerance();

                return (ISpatialReference)utm49N;
            }
            catch (Exception ex)
            {
                throw new Exception($"坐标系创建失败: {ex.Message}");
            }
        }

        // 新增导入方法（完善版本）
        private void ImportFeatureClasses(IWorkspace targetWorkspace, string featureDatasetName, string sourceShapefilePath)
        {
            IFeatureDataConverter2 featureDataConverter = null;
            IEnumInvalidObject invalidObjects = null;
            IWorkspace sourceWorkspace = null;

            try
            {
                // ========== 1. 准备源数据（Shapefile） ==========
                // 获取Shapefile所在目录
                string shpDirectory = System.IO.Path.GetDirectoryName(sourceShapefilePath);
                string shpName = System.IO.Path.GetFileNameWithoutExtension(sourceShapefilePath);

                // 打开Shapefile工作空间
                IWorkspaceFactory shpWorkspaceFactory = new ShapefileWorkspaceFactoryClass();
                sourceWorkspace = shpWorkspaceFactory.OpenFromFile(shpDirectory, 0);

                // 获取源要素类名称
                IFeatureClassName sourceFClassName = new FeatureClassNameClass
                {
                    WorkspaceName = ((IDataset)sourceWorkspace).FullName as IWorkspaceName,
                    FeatureType = esriFeatureType.esriFTSimple,
                    ShapeFieldName = "Shape"
                };
                ((IDatasetName)sourceFClassName).Name = shpName;

                // ========== 2. 准备目标数据（File GDB FeatureDataset） ==========
                // 打开目标要素数据集
                IFeatureWorkspace targetFeatureWorkspace = (IFeatureWorkspace)targetWorkspace;
                IFeatureDataset featureDataset = targetFeatureWorkspace.OpenFeatureDataset(featureDatasetName);

                // 创建目标要素类名称
                IFeatureClassName targetFClassName = new FeatureClassNameClass
                {
                    WorkspaceName = ((IDataset)featureDataset).Workspace as IWorkspaceName,
                    FeatureType = esriFeatureType.esriFTSimple
                };
                ((IDatasetName)targetFClassName).Name = shpName; // 保持相同名称

                // ========== 3. 获取源字段结构 ==========
                IFeatureClass sourceFC = ((IFeatureWorkspace)sourceWorkspace).OpenFeatureClass(shpName);
                IFields sourceFields = sourceFC.Fields;

                // ========== 4. 构建几何定义（从源数据获取，确保与数据集空间参考一致） ==========
                IGeometryDef geometryDef = GetGeometryDefFromSource(sourceFC);

                // ========== 5. 执行转换 ==========
                featureDataConverter = new FeatureDataConverterClass();
                invalidObjects = featureDataConverter.ConvertFeatureClass(
                    (IDatasetName)sourceFClassName,    // 源要素类路径
                    null,                              // 无查询过滤
                    null,                              // 无选择集
                    (IFeatureDatasetName)((IDataset)featureDataset).FullName, // 目标要素数据集名称
                    targetFClassName,                  // 目标要素类名称
                    geometryDef,                       // 几何定义（直接从源获取）
                    sourceFields,                      // 使用源字段结构
                    "",                                // 无配置关键字（Personal GDB）
                    1000,                              // 每1000个要素刷新一次
                    0                                  // 无父窗口句柄
                );

                // ========== 6. 检查错误 ==========
                if (invalidObjects != null)
                {
                    IInvalidObjectInfo invalidInfo = invalidObjects.Next();
                    if (invalidInfo != null)
                    {
                        throw new Exception($"转换错误: 要素ID {invalidInfo.InvalidObjectID} - {invalidInfo.ErrorDescription}");
                    }
                }

                // 强制释放COM对象
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(featureDataConverter);
            }
            catch (Exception ex)
            {
                throw new Exception($"数据导入失败: {ex.Message}");
            }
            finally
            {
                // 显式清理所有COM对象
                if (sourceWorkspace != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(sourceWorkspace);
                if (invalidObjects != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(invalidObjects);
            }
        }

        // 从源要素类获取几何定义
        private IGeometryDef GetGeometryDefFromSource(IFeatureClass sourceFC)
        {
            try
            {
                int shapeFieldIndex = sourceFC.FindField("Shape");
                IField shapeField = sourceFC.Fields.get_Field(shapeFieldIndex);
                return shapeField.GeometryDef;
            }
            catch
            {
                throw new Exception("无法从源要素类获取几何定义");
            }
        }

        // 辅助方法：从工作空间获取要素数据集名称
        private IFeatureDatasetName FeatureDatasetNameFromWorkspace(IFeatureWorkspace workspace, string datasetName)
        {
            IDataset dataset = workspace.OpenFeatureDataset(datasetName) as IDataset;
            return (IFeatureDatasetName)dataset.FullName;
        }

        private void CreateNetworkDataset(IWorkspace workspace, string featureDatasetName, string sourceFeatureClassName, string NetworkDatasetName)
        {
            IDENetworkDataset deNetworkDataset = new DENetworkDatasetClass();
            deNetworkDataset.Buildable = true;//允许构建

            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
            IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(featureDatasetName);

            IGeoDataset geoDataset = (IGeoDataset)featureClass;
            IDEGeoDataset deGeoDataset = (IDEGeoDataset)deNetworkDataset;
            deGeoDataset.Extent = geoDataset.Extent;//范围
            deGeoDataset.SpatialReference = geoDataset.SpatialReference;//空间参考

            IDataElement dataElement = (IDataElement)deNetworkDataset;
            dataElement.Name = NetworkDatasetName;//网络数据集名称

            IEdgeFeatureSource streetsEdgeFeatureSource = new EdgeFeatureSourceClass();
            INetworkSource streetsNetworkSource = (INetworkSource)streetsEdgeFeatureSource;
            streetsNetworkSource.Name = sourceFeatureClassName;//边源数据名称
            streetsNetworkSource.ElementType = esriNetworkElementType.esriNETEdge;

            streetsEdgeFeatureSource.UsesSubtypes = false;//禁用子类型
            streetsEdgeFeatureSource.ClassConnectivityGroup = 1;//分组1组
            //连通性
            streetsEdgeFeatureSource.ClassConnectivityPolicy = esriNetworkEdgeConnectivityPolicy.esriNECPEndVertex;

            IStreetNameFields streetNameFields = new StreetNameFieldsClass();
            streetNameFields.Priority = 1;
        }

        private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {

        }


        // 添加类级变量存储不同标记
        private IElement m_startMarker, m_startText; // 起点相关元素
        private IElement m_endMarker, m_endText;     // 终点相关元素
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                if (m_startPoint == null)
                {
                    MessageBox.Show("请先选择起点位置", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                // 设置地图控件为选择终点模式
                axMapControl1.CurrentTool = null;
                axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;

                // 提示用户选择终点
                MessageBox.Show("请在地图上点击选择终点位置", "选择终点", MessageBoxButtons.OK, MessageBoxIcon.Information);

                // 设置地图控件的鼠标点击事件处理
                axMapControl1.OnMouseDown += SelectEndPoint;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择终点失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SelectEndPoint(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            try
            {
                axMapControl1.OnMouseDown -= SelectEndPoint;

                // 清除旧终点
                ClearMarkers(ref m_endMarker, ref m_endText);

                m_endPoint = new PointClass();
                m_endPoint.PutCoords(e.mapX, e.mapY);

                // 添加isStartPoint参数
                MarkPointOnMap(m_endPoint, "终点", Color.Red, false);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择终点失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                // 清除之前的选择和标记
                ClearSelection();
                ClearStartPointMarker();  // 新增方法，专门清除起点标记

                // 设置地图控件为选择起点模式
                axMapControl1.CurrentTool = null;
                axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;

                // 提示用户选择起点
                MessageBox.Show("请在地图上点击选择起点位置", "选择起点", MessageBoxButtons.OK, MessageBoxIcon.Information);

                // 设置地图控件的鼠标点击事件处理
                axMapControl1.OnMouseDown += SelectStartPoint;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择起点失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SelectStartPoint(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            try
            {
                axMapControl1.OnMouseDown -= SelectStartPoint;

                // 清除旧起点
                ClearMarkers(ref m_startMarker, ref m_startText);

                m_startPoint = new PointClass();
                m_startPoint.PutCoords(e.mapX, e.mapY);

                // 添加isStartPoint参数
                MarkPointOnMap(m_startPoint, "起点", Color.Green, true);

                MessageBox.Show("起点已选择", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择起点失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void ClearStartPointMarker()
        {
            // 这里需要根据您实际存储标记元素的方式来实现
            // 以下是示例代码，您需要根据实际情况调整

            // 如果使用GraphicsLayer来存储标记
            IGraphicsContainer graphicsContainer = axMapControl1.Map as IGraphicsContainer;
            graphicsContainer.Reset();
            IElement element = graphicsContainer.Next();
            while (element != null)
            {
                // 检查是否是起点标记（可以根据某些特征判断，如颜色或标签）
                if (element is ITextElement && ((ITextElement)element).Text == "这里是起点")
                {
                    graphicsContainer.DeleteElement(element);
                    break;
                }
                element = graphicsContainer.Next();
            }

            // 刷新地图显示
            axMapControl1.Refresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }
        

        // 在窗体类中添加网络分析图层引用
        private INetworkLayer m_networkLayer;

        private void FindShortestPath(IPoint startPoint, IPoint endPoint)
        {
            try
            {
                string pointInfo = $"起点: X={startPoint.X}, Y={startPoint.Y}\n" +
                          $"终点: X={endPoint.X}, Y={endPoint.Y}";
                MessageBox.Show(pointInfo, "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);

                // 1. 获取网络分析图层
                m_networkLayer = GetNetworkLayer();
                if (m_networkLayer == null)
                {
                    MessageBox.Show("未找到有效的网络分析图层", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 2. 创建路径分析类实例
                RouteClass routeCalculator = new RouteClass();

                if (startPoint == null || endPoint == null) return;
                // 4. 执行路径分析
                routeCalculator.easySolveRoute(startPoint, endPoint);

                // 5. 获取分析结果并添加到地图
                IFeatureLayer routeLayer = routeCalculator.GetRouteLayer();
                if (routeLayer != null)
                {
                    axMapControl1.AddLayer(routeLayer);
                    axMapControl1.Refresh();
                    MessageBox.Show("最短路径分析完成!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("未生成路径结果", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception ex)
            {
              
        
            }

        }


        private void MarkPointOnMap(IPoint point, string label, Color color, bool isStartPoint)
        {
            try
            {
                if (m_graphicsContainer == null)
                {
                    m_graphicsContainer = axMapControl1.Map as IGraphicsContainer;
                }

                // 清除对应类型的旧标记
                if (isStartPoint)
                {
                    ClearMarkers(ref m_startMarker, ref m_startText);
                }
                else
                {
                    ClearMarkers(ref m_endMarker, ref m_endText);
                }

                // 创建标记符号（圆形样式）
                ISimpleMarkerSymbol markerSymbol = new SimpleMarkerSymbolClass();
                markerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                markerSymbol.Color = GetEsriColor(color);
                markerSymbol.Size = 12;
                markerSymbol.Outline = true;
                markerSymbol.OutlineColor = GetEsriColor(Color.White);
                markerSymbol.OutlineSize = 2;

                // 创建点元素
                IMarkerElement markerElement = new MarkerElementClass();
                markerElement.Symbol = markerSymbol;
                IElement element = (IElement)markerElement;
                element.Geometry = point;

                // 创建带偏移的文本元素
                ITextElement textElement = CreateTextElement(point, label, 15);

                // 存储元素引用
                if (isStartPoint)
                {
                    m_startMarker = element;
                    m_startText = (IElement)textElement;
                }
                else
                {
                    m_endMarker = element;
                    m_endText = (IElement)textElement;
                }

                // 添加元素到容器
                m_graphicsContainer.AddElement(element, 0);
                m_graphicsContainer.AddElement((IElement)textElement, 0);

                axMapControl1.ActiveView.PartialRefresh(
                    esriViewDrawPhase.esriViewGraphics,
                    null,
                    axMapControl1.ActiveView.Extent);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"标记创建失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void ClearMarkers(ref IElement markerElement, ref IElement textElement)
        {
            if (m_graphicsContainer != null)
            {
                if (markerElement != null)
                {
                    m_graphicsContainer.DeleteElement(markerElement);
                    markerElement = null;
                }
                if (textElement != null)
                {
                    m_graphicsContainer.DeleteElement(textElement);
                    textElement = null;
                }
            }
            axMapControl1.ActiveView.PartialRefresh(
                esriViewDrawPhase.esriViewGraphics,
                null,
                axMapControl1.ActiveView.Extent);
        }
        private ITextElement CreateTextElement(IPoint basePoint, string text, double offsetY)
        {
            // 创建偏移点
            IPoint textPoint = new PointClass();
            textPoint.PutCoords(basePoint.X, basePoint.Y + ToMapUnits(offsetY));

            // 创建文本符号
            ITextSymbol textSymbol = new TextSymbolClass();
            textSymbol.Color = GetEsriColor(Color.Black);

            // 正确转换字体对象（添加显式类型转换）
            IFontDisp font = (IFontDisp)new StdFontClass(); // 关键修正点
            font.Name = "微软雅黑";
            font.Size = 10;
            font.Bold = true;

            textSymbol.Font = font;

            // 创建文本元素
            ITextElement textElement = new TextElementClass();
            textElement.Symbol = textSymbol;
            textElement.Text = text;
            ((IElement)textElement).Geometry = textPoint;

            return textElement;
        }

        

        // 像素转地图单位（假设地图单位为米）
        private double ToMapUnits(double pixels)
        {
            // 根据地图比例尺计算实际偏移量
            double dpi = 96; // 标准屏幕DPI
            return (pixels / dpi) * 0.0254 * axMapControl1.MapScale;
        }
        private void DrawRouteOnMap(IGeometry geometry)
        {
            if (m_graphicsContainer == null)
            {
                m_graphicsContainer = axMapControl1.Map as IGraphicsContainer;
            }

            // 清除之前的路径
            if (m_routeElement != null)
            {
                m_graphicsContainer.DeleteElement(m_routeElement);
            }

            // 创建路径符号
            ISimpleLineSymbol lineSymbol = new SimpleLineSymbol();
            lineSymbol.Color = GetEsriColor(Color.Blue);
            lineSymbol.Width = 3;
            lineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;

            // 创建路径元素
            ILineElement lineElement = (ILineElement)new LineElement();
            lineElement.Symbol = lineSymbol;
            m_routeElement = (IElement)lineElement;
            m_routeElement.Geometry = geometry;

            // 添加到地图
            m_graphicsContainer.AddElement(m_routeElement, 0);

            // 刷新视图
            axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }

        // 清除选择
        private void ClearSelection()
        {
            // 清除起点
            ClearMarkers(ref m_startMarker, ref m_startText);

            // 清除终点
            ClearMarkers(ref m_endMarker, ref m_endText);

            // 清除路径
            if (m_routeElement != null)
            {
                m_graphicsContainer.DeleteElement(m_routeElement);
                m_routeElement = null;
            }

            axMapControl1.ActiveView.PartialRefresh(
                esriViewDrawPhase.esriViewGraphics,
                null,
                axMapControl1.ActiveView.Extent);
        }

        private INetworkLayer GetNetworkLayer()
        {
            bool foundNetworkLayer = false;

            for (int i = 0; i < axMapControl1.LayerCount; i++)
            {
                ILayer layer = axMapControl1.get_Layer(i);
                if (layer is INetworkLayer networkLayer)
                {
                    foundNetworkLayer = true;  // 标记已找到网络图层

                    // 验证是否包含有效网络数据集
                    if (networkLayer.NetworkDataset != null)
                    {
                        return networkLayer;
                    }
                }
            }

            // 循环结束后统一提示
            if (!foundNetworkLayer)
            {
                MessageBox.Show("地图中未找到任何网络分析图层", "网络图层缺失",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                MessageBox.Show("找到网络图层但未包含有效网络数据集", "数据集错误",
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            return null;
        }

        // 将System.Drawing.Color转换为ESRI颜色
        private IColor GetEsriColor(Color color)
        {
            IRgbColor rgbColor = new RgbColor();
            rgbColor.Red = color.R;
            rgbColor.Green = color.G;
            rgbColor.Blue = color.B;
            return (IColor)rgbColor;
        }
    }
}
